home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
-
- #----------------------------------------------------------------------
- # variables you might have to change:
-
- $nntp_server = "news.cis.umn.edu";
- $nntp_port = 119;
- $nntp_defart = "article";
- $nntp_groups = "/etc/go4gw/ACTIVE"; # could be active file
- $nntp_reverse = 0; # to list articles in reverse order
-
- #----------------------------------------------------------------------
-
- @nntp_acl=(
- # ipaddress group access + = allow, - = deny
- '^134.84\. .* +',
- '^128.101\. .* +',
- '^131.212\. .* +',
- '^146.57\. .* +',
- '.* ^clari -',
- '.* .* +'
- );
- # end of variables
-
- # Commands this server responds to:
- #
- # "" -> list top level groups
- # ls [$group] [$range] -> list group's articles and sub-groups
- # lsa [$group] [$range] -> like "", sends "article" & "lsa" commands back
- # lsb [$group] [$range] -> "" sends "body" & "lsb" commands back
- # lsh [$group] [$range] -> "" sends "header" & "lsh" commands back
- # article <id> -> get article by ID
- # article $group $number -> get 1 article, number can be "last" or "first",
- # or any numeric perl expression.
- # body <id> -> like article, but just get text
- # body $group $number -> ""
- # head <id> -> like article, but just get header
- # head $group $number -> ""
- # sorry -> send sorry message
- #
- # The optional $range arguement has the following format:
- # n - return 'n' most recent articles
- # x:y - return articles x through y (inclusive)
- # x and y can both be numeric perl expressions. The
- # string 'last' is replaced with the last article in the
- # group, and the string 'first' is replaced with the first.
- # first:last - all articles (same as not specifiying a range
- # last:first - all articles (in reverse order)
- # last-9:last - return last 10 articles (same as specifiying 10)
- # last:last-9 - return last 10 articles in reverse order
-
-
- sub nntp_main {
- local($_) = @_;
-
- &do_ls("",$nntp_defart,"ls") if /^$/;
- &do_ls("",$nntp_defart,"ls") if /^ls\s*$/;
- &do_ls($1,$nntp_defart,"ls") if /^ls\s+(.*)/i;
-
- &do_ls("","article","lsa") if /^lsa\s*$/;
- &do_ls($1,"article","lsa") if /^lsa\s+(.*)/i;
-
- &do_ls("","body","lsb") if /^lsb\s*$/;
- &do_ls($1,"body","lsb") if /^lsb\s+(.*)/i;
-
- &do_ls("","head","lsh") if /^lsh\s*$/;
- &do_ls($1,"head","lsh") if /^lsh\s+(.*)/i;
-
- &do_article($1,$2,"ARTICLE") if /^article\s+(\S+)\s+(\S+)/i;
- &do_article_id($1,"ARTICLE") if /^article\s+(<.*>)/i;
-
- &do_article($1,$2,"HEAD") if /^head\s+(\S+)\s+(\S+)/i;
- &do_article_id($1,"HEAD") if /^head\s+(<.*>)/i;
-
- &do_article($1,$2,"BODY") if /^body\s+(\S+)\s+(\S+)/i;
- &do_article_id($1,"BODY") if /^body\s+(<.*>)/i;
-
- &Gsorry if /^sorry$/;
- &Gabort("Unknown command!");
- exit;
- }
-
- sub do_article_id {
- local($id,$cmd) = @_;
- &open_nntp;
- &Gsend("$cmd $id");
- $_ = &Grecv;
- &Gabort($_) if !/^2/;
-
- while(<GSERVER>) {
- print;
- last if /^\.\r\n$/;
- }
-
- &close_nntp;
- exit;
-
- }
-
- sub do_article {
- local($group,$number,$cmd) = @_;
-
- if (&check_access($group) eq '-') { &Gsorry; }
- &open_nntp;
-
- &Gsend("GROUP $group");
- $_ = &Grecv;
- &Gabort($_) if !/^2/;
- ($n,$f,$l) = /\d+\s+(\d+)\s+(\d+)\s+(\d+)/;
-
- $number =~ s/first/\$f/g;
- $number =~ s/last/\$l/g;
- $number = int(eval($number));
-
- &Gsend("$cmd $number");
- $_ = &Grecv;
- &Gabort($_) if !/^2/;
-
- while(<GSERVER>) {
- print;
- last if /^\.\r\n$/;
- }
-
- &close_nntp;
- exit;
- }
-
- sub list_group {
- local($group,$type,$range) = @_;
-
- &Gsend("GROUP $group");
- $_ = &Grecv;
- &Gabort($_) if !/^211/;
-
- ($n,$f,$l) = /211\s+(\d+)\s+(\d+)\s+(\d+)/;
-
- if ($range =~ /^(\S+):(\S+)$/) {
- $low = $1; $high = $2;
- $low =~ s/first/\$f/g;
- $low =~ s/last/\$l/g;
- $high =~ s/first/\$f/g;
- $high =~ s/last/\$l/g;
- $low = int(eval($low));
- $high = int(eval($high));
- if ($low > $l) { $low = $l; }
- elsif ($low < $f) {$low = $f; }
- if ($high > $l) { $high = $l; }
- elsif ($high < $f) {$high = $f; }
-
- if ($high < $low) { $f = $high; $l = $low; $nntp_reverse=1; }
- if ($low <= $high) { $f = $low; $l = $high; $nntp_reverse=0; }
-
- }
- elsif ($range ne '') {
- $range =~ s/first/\$f/g;
- $range =~ s/last/\$l/g;
- $range = int(eval($range));
- if ($range >0 && $range < $n) { $f = $l - $range + 1; }
- }
-
- &Gsend("XHDR Subject $f-$l");
- $_ = &Grecv;
- &Gabort($_) if !/^221/;
-
- while(<GSERVER>) {
- chop; chop;
- last if /^\.$/;
- ($article,$subject) = /^(\d+)\s+(.*)/;
- $subject =~ s/\t/ /g; # just in case!
- if ($nntp_reverse) {
- push(@reply,"0$subject\t$Ggw $atype $group $article\t$Ghost\t$Gport");
- } else {
- &Greply("0$subject\t$Ggw $atype $group $article\t$Ghost\t$Gport");
- }
- }
-
- if ($nntp_reverse) {
- for ($i=$#reply; $i!= -1; $i--) { &Greply($reply[$i]); }
- }
-
- &Greply(".");
- &close_nntp;
- exit;
- }
-
- sub do_ls {
- local($prefix,$atype,$lscmd) = @_;
- local($range);
-
- $prefix =~ s/\s+$//;
-
- if ($prefix =~ /(\S+)\s+(\S+)/) {
- $prefix = $1;
- $range = $2;
- }
- elsif (($prefix =~ /^\d+$/) || ($prefix =~ /:/)) {
- $range = $prefix;
- $prefix = "";
- }
-
- if (&check_access($prefix) eq '-') {
- &Greply("0Sorry! No access off of campus!\t$Ggw sorry\t$Ghost\t$Gport");
- &Greply(".");
- exit;
- }
-
- &open_nntp;
- &get_groups;
-
- foreach ( sort @groups) {
- if ($_ eq $prefix) { $do_list_group = $_; }
- elsif (/^$prefix\.([^.]*)\.?/) {
- $leaf=$1;
- $save{"$prefix.$leaf"} = "1$leaf\t$Ggw $lscmd $prefix.$leaf $range\t$Ghost\t$Gport";
- }
- elsif ($prefix eq '' && /([^.]*)/) {
- $save{"$1"} = "1$1\t$Ggw $lscmd $1 $range\t$Ghost\t$Gport";
- }
- }
-
- foreach ( sort keys %save) { &Greply($save{$_}); }
- &list_group($do_list_group,$atype,$range) if ($do_list_group);
-
- &Greply(".");
- &close_nntp;
- exit;
- }
-
- sub open_nntp {
- local($_);
- &GopenServer($nntp_server,$nntp_port);
- $_ = &Grecv;
- &Gabort($_) if !/^2/;
- }
-
- sub close_nntp {
- &Gsend("QUIT");
- close(GSERVER);
- }
-
- sub get_groups {
- if (open(GROUPS,$nntp_groups)) {
- while(<GROUPS>) {
- chop;
- ($grp) = /^(\S+)/;
- push(@groups,$grp);
- }
- close(GROUPS);
- } else { # can't open file, get list from server!
- &load_groups;
- }
- }
-
- sub load_groups {
-
- &open_nntp;
- &Gsend("LIST");
- $_ = &Grecv;
- &Gabort($_) if !/^215/;
-
- while(<GSERVER>) {
- chop; chop;
- last if /^\.$/;
- s/^(\S+).*/$1/;
- push(@groups,$_);
- }
-
- }
-
- sub create_groups {
- &load_groups;
- open(GROUPS,">$nntp_groups") || die "$nntp_groups: $!";
- foreach (@groups) { print GROUPS "$_\n"; }
- close GROUPS;
- &close_nntp;
- exit;
- }
-
- sub check_access {
- local($group)=@_;
-
- return 1 if (-t STDIN);
- $sockaddr = 'S n a4 x8';
- $mysockaddr = getpeername(STDIN);
- ($ramily,$rport,$raddr) = unpack($sockaddr,$mysockaddr);
- ($a,$b,$c,$d) = unpack('C4',$raddr);
- $ipaddress = "$a.$b.$c.$d";
-
- foreach (@nntp_acl) {
- ($ipacl,$groupacl,$access)=split;
- return $access if ($ipaddress =~ /$ipacl/) && ($group =~ /$groupacl/);
- }
- return '-'; #default is to restrict access
- }
-
- 1; # for require
-
-
-
-